const QuestionSet = require('../models/QuestionSet')
const QuestionSetExercise = require('../models/QuestionSetExercise')
const QuestionSetAnswer = require('../models/QuestionSetAnswer')
const Question = require('../models/Question')
const WrongQuestion = require('../models/WrongQuestion')
const QuestionSetItem = require('../models/QuestionSetItem')
const sequelize = require('../db/db');
const { Op } = require('sequelize');
const { sendResponse, sendListResponse } = require('../utils/response');
const { getTimestamp, getTwoDigits, formatObject, formatTime } = require('../utils/common');

/**
 * 开始题库练习 - 获取题库所有题目
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
const startExercise = async (req, res) => {
  const transaction = await sequelize.transaction();
  try {
    const { setId, userId } = req.body;

    // 验证参数
    if (!setId) {
      return sendResponse(res, 500, '参数错误: 题库ID不能为空');
    }

    if (!userId) {
      return sendResponse(res, 500, '参数错误: 用户ID不能为空');
    }

    // 验证题库是否存在
    const questionSet = await QuestionSet.findOne({
      where: {
        id: setId
      }
    });

    if (!questionSet) {
      return sendResponse(res, 500, '题库不存在');
    }

    // 检查题库是否有题目
    if (questionSet.question_count === 0) {
      return sendResponse(res, 500, '题库中没有题目, 无法开始练习');
    }

    // 获取题库中的所有题目及其顺序
    const questionItems = await QuestionSetItem.findAll({
      where: {
        set_id: setId
      },
      include: [{
        model: Question,
        as: 'question',
        attributes: ['id', 'content', 'options', 'difficulty', 'category_id', 'correct_key']
      }],
      order: [['order_num', 'ASC']]
    });

    if (questionItems.length === 0) {
      return sendResponse(res, 500, '题库中没有题目, 无法开始练习');
    }

    // 提取题目ID列表和题目详情
    const questionIds = questionItems.map(item => item.question_id);
    const questions = questionItems.map(item => formatObject({
      id: item.question.id,
      content: item.question.content,
      options: item.question.options,
      difficulty: item.question.difficulty,
      categoryId: item.question.category_id,
      correctKey: item.question.correct_key,
      orderNum: item.order_num
    }));

    // 生成练习ID
    const id = "196" + getTimestamp() + getTwoDigits();

    // 创建练习记录
    const exercise = await QuestionSetExercise.create({
      id,
      user_id: userId,
      set_id: setId,
      status: 0, // 进行中
      question_sequence: questionIds,
      current_index: 0,
      correct_count: 0,
      start_time: formatTime(new Date())
    }, { transaction });

    await transaction.commit();

    // 格式化返回数据，包含所有题目
    sendResponse(res, 200, '练习开始成功', formatObject({
      exerciseId: exercise.id,
      setId: exercise.set_id,
      setName: questionSet.name,
      totalQuestions: questionIds.length,
      questions: questions
    }));
  } catch (error) {
    await transaction.rollback();
    console.error('开始题库练习失败:', error);
    sendResponse(res, 500, '开始题库练习失败', error.message);
  }
};

/**
 * 提交题目答案 - 批量提交所有答案
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
const submitAnswer = async (req, res) => {
  const transaction = await sequelize.transaction();
  try {
    const { exerciseId, answers, userId } = req.body;
    // answers格式: [{questionId: '123', answer: 'A'}, {questionId: '456', answer: 'B'}, ...]

    // 验证参数
    if (!exerciseId || !answers || !Array.isArray(answers) || answers.length === 0) {
      return sendResponse(res, 500, '参数错误: 练习ID和答案列表不能为空');
    }

    if (!userId) {
      return sendResponse(res, 500, '参数错误: 用户ID不能为空');
    }


    // 验证练习是否存在且为当前用户的
    const exercise = await QuestionSetExercise.findOne({
      where: {
        id: exerciseId,
        user_id: userId,
        status: 0 // 进行中
      }
    });

    if (!exercise) {
      return sendResponse(res, 500, '练习不存在或已完成');
    }

    // 获取练习的题目序列
    const questionSequence = exercise.question_sequence;

    // 验证所有题目ID是否有效
    const questionIds = answers.map(a => a.questionId);
    const invalidQuestionIds = questionIds.filter(id => !questionSequence.includes(id));

    if (invalidQuestionIds.length > 0) {
      return sendResponse(res, 400, `以下题目ID不属于该练习: ${invalidQuestionIds.join(', ')}`);
    }

    // 查询所有题目以获取正确答案
    const questions = await Question.findAll({
      where: {
        id: questionIds
      },
      attributes: ['id', 'correct_key']
    });

    // 创建题目ID到正确答案的映射
    const questionCorrectAnswers = {};
    questions.forEach(q => {
      questionCorrectAnswers[q.id] = q.correct_key;
    });

    // 处理每个答案
    let correctCount = 0;
    const answerRecords = [];

    for (const answerItem of answers) {
      const { questionId, answer } = answerItem;
      const correctAnswer = questionCorrectAnswers[questionId];

      if (!correctAnswer) {
        continue; // 跳过找不到正确答案的题目
      }

      // 判断答案是否正确
      const isCorrect = correctAnswer === answer ? 1 : 0;

      if (isCorrect) {
        correctCount++;
      } else {
        // 如果答错，记录到错题本
        const existingWrong = await WrongQuestion.findOne({
          where: {
            user_id: userId,
            question_id: questionId
          },
          transaction
        });

        if (existingWrong) {
          // 更新错题记录
          await existingWrong.update({
            error_count: existingWrong.error_count + 1,
            last_wrong_time: formatTime(new Date())
          }, { transaction });
        } else {
          // 创建新的错题记录
          const wrongId = "191" + getTimestamp() + getTwoDigits();
          await WrongQuestion.create({
            id: wrongId,
            user_id: userId,
            question_id: questionId,
            error_count: 1,
            last_wrong_time: formatTime(new Date())
          }, { transaction });
        }
      }

      // 生成答题记录ID
      const answerId = "195" + getTimestamp() + getTwoDigits();

      // 准备答题记录
      answerRecords.push({
        id: answerId,
        exercise_id: exerciseId,
        question_id: questionId,
        answer,
        is_correct: isCorrect,
        answer_time: formatTime(new Date())
      });
    }

    // 批量创建答题记录
    await QuestionSetAnswer.bulkCreate(answerRecords, { transaction });

    // 更新练习记录
    await exercise.update({
      status: 1, // 已完成
      current_index: questionSequence.length, // 设置为题目总数，表示已完成所有题目
      correct_count: correctCount,
      end_time: formatTime(new Date())
    }, { transaction });

    await transaction.commit();

    // 返回练习结果
    const exerciseResult = await getExerciseResult(exerciseId);
    return sendResponse(res, 200, '练习完成', formatObject({
      exerciseId,
      result: exerciseResult
    }));
  } catch (error) {
    await transaction.rollback();
    console.error('提交答案失败:', error);
    sendResponse(res, 500, '提交答案失败', error.message);
  }
};

/**
 * 获取练习结果
 * @param {string} exerciseId - 练习ID
 * @returns {Object} 练习结果
 */
const getExerciseResult = async (exerciseId) => {
  const exercise = await QuestionSetExercise.findByPk(exerciseId, {
    include: [
      {
        model: QuestionSet,
        as: 'questionSet',
        attributes: ['id', 'name']
      }
    ]
  });

  if (!exercise) {
    throw new Error('练习不存在');
  }

  // 获取所有答题记录
  const answers = await QuestionSetAnswer.findAll({
    where: {
      exercise_id: exerciseId
    },
    include: [
      {
        model: Question,
        as: 'question',
        attributes: ['id', 'content', 'options', 'correct_key', 'difficulty', 'category_id']
      }
    ],
    order: [['answer_time', 'ASC']]
  });

  // 计算统计数据
  const totalQuestions = exercise.question_sequence.length;
  const correctQuestions = exercise.correct_count;
  const incorrectQuestions = totalQuestions - correctQuestions;
  const accuracy = totalQuestions > 0 ? (correctQuestions / totalQuestions * 100).toFixed(2) : 0;

  // 格式化答题详情
  const answersFormatted = answers.map(answer => formatObject({
    questionId: answer.question_id,
    content: answer.question.content,
    options: answer.question.options,
    userAnswer: answer.answer,
    correctKey: answer.question.correct_key,
    isCorrect: answer.is_correct === 1,
    difficulty: answer.question.difficulty,
    categoryId: answer.question.category_id
  }));

  return {
    exerciseId: exercise.id,
    setId: exercise.set_id,
    setName: exercise.questionSet.name,
    startTime: formatTime(exercise.start_time),
    endTime: formatTime(exercise.end_time),
    totalQuestions,
    correctQuestions,
    incorrectQuestions,
    accuracy,
    details: answersFormatted
  };
};

/**
 * 获取练习结果
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
const getExerciseResultById = async (req, res) => {
  try {
    const { exerciseId } = req.params;

    // 验证练习是否存在且为当前用户的
    const exercise = await QuestionSetExercise.findOne({
      where: {
        id: exerciseId
      }
    });

    if (!exercise) {
      return sendResponse(res, 500, '练习不存在');
    }

    // 如果练习未完成，则返回错误
    if (exercise.status === 0) {
      return sendResponse(res, 500, '练习尚未完成');
    }

    const result = await getExerciseResult(exerciseId);
    sendResponse(res, 200, '获取练习结果成功', formatObject(result));
  } catch (error) {
    console.error('获取练习结果失败:', error);
    sendResponse(res, 500, '获取练习结果失败', error.message);
  }
};

/**
 * 获取练习历史
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 */
const getExerciseHistory = async (req, res) => {
  try {
    const { userId, page = 1, pageSize = 10 } = req.query;

    if (!userId) {
      return sendResponse(res, 400, '参数错误: 用户ID不能为空');
    }

    // 确保页码和页大小是有效的数字
    const parsedPage = Math.max(1, parseInt(page) || 1);
    const parsedPageSize = Math.max(1, parseInt(pageSize) || 10);
    const offset = (parsedPage - 1) * parsedPageSize;

    // 查询练习历史
    const { count, rows } = await QuestionSetExercise.findAndCountAll({
      where: {
        user_id: userId,
        status: 1, // 只包括已完成的
        end_time: { [Op.ne]: null } // 确保有结束时间
      },
      include: [
        {
          model: QuestionSet,
          as: 'questionSet',
          attributes: ['id', 'name'],
          required: false // 允许外连接以处理题库可能已删除的情况
        }
      ],
      limit: parsedPageSize,
      offset: offset,
      order: [['end_time', 'DESC']]
    });

    // 安全地格式化返回数据
    const formattedHistory = rows.map(exercise => {
      // 安全地处理可能为null的属性
      const questionSequence = Array.isArray(exercise.question_sequence) ? exercise.question_sequence : [];
      const totalQuestions = questionSequence.length;
      const correctCount = Number(exercise.correct_count) || 0;

      // 计算准确率，避免除以零错误
      let accuracy = 0;
      if (totalQuestions > 0 && correctCount >= 0) {
        accuracy = ((correctCount / totalQuestions) * 100).toFixed(2);
        // 确保结果是有效数字
        accuracy = isNaN(accuracy) ? 0 : accuracy;
      }

      return {
        exerciseId: exercise.id,
        setId: exercise.set_id,
        setName: exercise.questionSet ? exercise.questionSet.name : '未知题库',
        startTime: formatTime(exercise.start_time),
        endTime: formatTime(exercise.end_time),
        totalQuestions: totalQuestions,
        correctQuestions: correctCount,
        accuracy: accuracy,
        status: exercise.status
      };
    });

    sendListResponse(res, 200, '获取练习历史成功', formattedHistory, count);
  } catch (error) {
    console.error('获取练习历史失败:', error);
    sendResponse(res, 500, '获取练习历史失败', error.message || '服务器内部错误');
  }
};


module.exports = {
  startExercise,
  submitAnswer,
  getExerciseResultById,
  getExerciseHistory
}; 